<?php declare(strict_types=1);

namespace App\Api\V2\Controller\Embed;

use App\Api\Controllers\BaseController;
use App\Exceptions\BizException;
use App\Models\CommonConfigs;
use App\Models\CommonMchStores;
use App\Models\CommonMchStoresV2;
use App\Models\Store;
use App\Services\Pay\GuoTonXinYi\Config;
use App\Services\Pay\GuoTonXinYi\Notify;
use App\Services\Pay\GuoTonXinYi\Pay;
use App\Services\Pay\ResultVo;
use App\Traits\ResponseTrait;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

class GtxyController extends BaseController
{
    use ResponseTrait;

    protected function payStoreWays(string $store_id, string $company): string
    {
        $store = Store::query()->where("store_id", $store_id)->first();
        if (empty($store)) {
            throw new BizException("店铺不存在");
        }
        if ($company == "gtxy") {
            $query = CommonMchStores::query();
        } else if ($company == "gtxy_v2") {
            $query = CommonMchStoresV2::query();
        }
        $mchInfo = (clone $query)->where("store_id", $store->store_id)->first();
        if (empty($mchInfo) && !empty($store->pid)) {
            $pStore = Store::query()->where("id", $store->pid)->first();
            if (empty($pStore)) {
                throw new BizException("主店不存在");
            }
            $mchInfo = (clone $query)->where("store_id", $pStore->store_id)->first();
        }
        if (empty($mchInfo)) {
            throw new BizException("商户号不存在");
        }
        return (string)$mchInfo->mch_no;
    }


    public function embedQuery(Request $request): string
    {
        try {
            $data = $request->all();
            $data["company"] = "gtxy";
            $validator = Validator::make($data, [
                "store_id" => "required",
                "company" => ["required", Rule::in(["gtxy", "gtxy_v2"])],
                "total_amount" => ["required", "min:0", "numeric"]
            ]);
            if ($validator->fails()) {
                throw new BizException($validator->errors()->first());
            }
            $mchNo = $this->payStoreWays($data["store_id"], $data["company"]);
            $config = CommonConfigs::query()->where("config_id", "1234")->first();
            if (empty($config)) {
                throw new BizException("配置不存在");
            }
            $out_trade_no = date('YmdHis', time()) . substr(microtime(), 2, 6) . sprintf('%03d', rand(0, 999));
            $resultVo = Pay::embedQuery([
                "custId" => $mchNo,
                "sceneType" => "01",
                "orderNo" => $out_trade_no,
                "txamt" => $data["total_amount"],
                "remark" => $data["remark"] ?? "",
                "asyncNotify" => $data["asyncNotify"] ?? "",
            ], ["agetId" => $config->platform_id, "public_key" => $config->public_key]);

            if ($resultVo->getCode() != 1) {
                throw new BizException($resultVo->getMsg());
            }
            $response = $resultVo->getData();
            return $this->successResponse("ok", ["data" => $response]);
        } catch (\Exception $e) {
            return $this->errorResponse($e->getMessage());
        }
    }


    public function embedPay(Request $request): string
    {
        try {
            $data = $request->all();
//            $data["company"] = "gtxy";
            $validator = Validator::make($data, [
                "store_id" => "required",
                "company" => ["required", Rule::in(["gtxy", "gtxy_v2"])],
                "total_amount" => ["required", "min:0", "numeric"],
                "merchant_id" => ["required"],
                "ways_source" => ["required", Rule::in(["weixin", "alipay", "unionpay"])],
                "notify_url" => ["nullable"],
                "timestamp" => ["required"],
                "sign" => ["required"]
            ]);
            if ($validator->fails()) {
                throw new BizException($validator->errors()->first());
            }
            $sign = $data["sign"];
            unset($data["sign"]);
            //签名验证
            $string = Notify::getSignContent($data) . '&key=' . Notify::Key;
            Log::channel("gtxy")->info("embedPay", [
                "string" => $string,
                "req" => $data
            ]);
            $string = md5($string);
            if ($sign != $string) {
                throw new BizException("签名校验失败");
            }

            $mchNo = $this->payStoreWays($data["store_id"], $data["company"]);
            $config = CommonConfigs::query()->where("config_id", "1234")->first();
            if (empty($config)) {
                throw new BizException("配置不存在");
            }
            $out_trade_no = date('YmdHis', time()) . substr(microtime(), 2, 6) . sprintf('%03d', rand(0, 999));
            $resultVo = Pay::embedPay([
                "custId" => $mchNo,
                "orderNo" => $out_trade_no,
                "total_amount" => $data["total_amount"],
                "store_id" => $data["store_id"],
                "company" => $data["company"],
                "ways_source" => $data["ways_source"],
                "merchant_id" => $data["merchant_id"],
                "notify_url" => $data["notify_url"]??""
            ], ["agetId" => $config->platform_id, "public_key" => $config->public_key]);
            if ($resultVo->getCode() != 1) {
                throw new BizException($resultVo->getMsg());
            }
            $response = $resultVo->getData();
            return $this->successResponse("ok", ["data" => $response]);
        } catch (\Exception $e) {
            return $this->errorResponse($e->getMessage());
        }
    }

}